package com.zy.controller;

import com.sun.org.apache.xml.internal.security.utils.Base64;
import com.zy.entity.User;
import com.zy.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.*;;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.server.PathParam;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

/**
 * @author 张宇
 * @date 2021/7/26 17:59
 */
@Controller
public class LoginController
{

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @ResponseBody
    @GetMapping("/test")
    public String test()
    {
        return "test";
    }

    /**
     * 登录
     * @param username
     * @param password
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/login",method = {RequestMethod.GET,RequestMethod.POST})
    public Map<String,Object> login(@PathParam("username") String username, @PathParam("password") String password,
                                    @PathParam("uuid") String uuid, @PathParam("code") String code)
    {
        Map<String,Object> map = new HashMap<>();
        if(redisTemplate.opsForValue().get(uuid) == null || redisTemplate.opsForValue().get(uuid) == "")
        {
            map.put("message","验证码已经失效!");
            map.put("code",500);
            return map;
        }
        else if(!redisTemplate.opsForValue().get(uuid).equals(code))
        {
            map.put("message","验证码错误!");
            map.put("code",500);
            return map;
        }
        User user = userService.findUserByUsernameAndPassword(username, DigestUtils.md5DigestAsHex(password.getBytes()));
        if(user != null)
        {
            String token = "Bearer "+UUID.randomUUID()+UUID.randomUUID()+UUID.randomUUID()+UUID.randomUUID()+UUID.randomUUID();//生成令牌
            redisTemplate.opsForValue().set(token,user.getId(),Duration.ofHours(12L));
            map.put("Authorization",token);
            map.put("data",user);
            map.put("message","登录成功");
            map.put("code",100);
            return map;
        }
        map.put("token",null);
        map.put("data",null);
        map.put("message","登录失败");
        map.put("code",104);
        return map;
    }

    /**
     * 从token中得到用户登录信息
     * @param token
     * @return
     */
    @ResponseBody
    @GetMapping("/getUserMessageOfLogin")
    public Map<String,Object> getUserMessageOfLogin(@RequestHeader("Authorization") String token)
    {
        Map<String,Object> map = new HashMap<>();
        Object object = redisTemplate.opsForValue().get(token);
        User user = userService.findUserById((Integer) object);
        if (object != null)
        {
            map.put("token",token);
            map.put("data",user);
            map.put("message","获取用户信息成功");
            map.put("code",100);
            return map;
        }
        map.put("token",null);
        map.put("data",null);
        map.put("message","获取用户信息失败");
        map.put("code",104);
        return map;
    }

    /**
     * 退出
     * @param token
     * @return
     */
    @ResponseBody
    @GetMapping("/loginOut")
    public Map<String,Object> loginOut(@RequestHeader("Authorization") String token)
    {
        Map<String,Object> map = new HashMap<>();
        Boolean data = redisTemplate.delete(token);
        map.put("token",token);
        map.put("data",data);
        map.put("message","推出成功");
        map.put("code",100);
        return map;
    }

    /**
     * 通过id修改用户头像
     * @param id
     * @param headImg
     * @return
     */
    @ResponseBody
    @GetMapping("/upDateHeadImg")
    public Map<String,Object> upDateHeadImg(int id, String headImg)
    {
        Map<String,Object> map = new HashMap<>();
        userService.upDateHeadImgById(id,headImg);
        map.put("message","修改成功");
        map.put("code",100);
        return map;
    }

    /**
     * 生成验证码
     */
    @ResponseBody
    @GetMapping("/captcha")
    public Map<String,Object> getCode(HttpServletResponse response) throws IOException
    {
        String uuid = UUID.randomUUID().toString();
        String capStr = null, code = null;
        String str="abcdefghijklmnopqrstuvwsyz0123456789";
        StringBuilder sb=new StringBuilder(4);
        for(int i=0;i<4;i++)
        {
            char ch = str.charAt(new Random().nextInt(36));
            sb.append(ch);
        }
        capStr = sb.toString();
        BufferedImage image = yanzhengma(capStr);//用自己改的

        redisTemplate.opsForValue().set(uuid,capStr,Duration.ofMinutes(2L));

        FastByteArrayOutputStream os = new FastByteArrayOutputStream();// 转换流信息写出
        Map<String,Object> map = new HashMap<>();
        try
        {
            ImageIO.write(image, "jpg", os);
        }
        catch (IOException e)
        {
            map.put("code",500);
            map.put("msg","操作失败!");
            return map;
        }

        map.put("code",200);
        map.put("msg","操作成功!");
        map.put("uuid", uuid);
        map.put("img", Base64.encode(os.toByteArray()));
        return map;
    }

    /**
     * 画图片,自己改的
     * @param capStr
     * @return
     */
    protected BufferedImage yanzhengma(String capStr)
    {
        int IMG_HEIGHT = 83;//图片高度
        int IMG_WIDTH = 32;//图片宽度
        BufferedImage bufferedImage = new BufferedImage(IMG_HEIGHT, IMG_WIDTH, BufferedImage.TYPE_INT_RGB);//用于绘制图片，设置图片的长宽和图片类型（RGB)
        Graphics graphics = bufferedImage.getGraphics();//获取绘图工具
        graphics.setColor(new Color(250, 250, 250));//使用RGB设置背景颜色
        graphics.fillRect(0, 0, 100, 32);//填充矩形区域

        char[] codeChar = capStr.toCharArray();//验证码中所使用到的字符
        String captcha = "";//存放生成的验证码
        Random random = new Random();
        for(int i = 0; i < codeChar.length; i++)//循环将每个验证码字符绘制到图片上
        {
            graphics.setColor(new Color(random.nextInt(250), random.nextInt(250), random.nextInt(250)));
            graphics.setFont(new Font("楷体", Font.BOLD, 25));
            graphics.drawString(codeChar[i] + "", (i * 20) + 5, 24);//将一个字符绘制到图片上，并制定位置（设置x,y坐标）
            captcha += codeChar[i];
        }

        return bufferedImage;
    }

}
